
package com.gitee.jmash.rbac.mapper;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import com.crenjoy.proto.mapper.BeanMapper;
import com.crenjoy.proto.mapper.ProtoMapper;
import com.gitee.jmash.core.orm.DtoPage;
import com.gitee.jmash.core.orm.DtoTotal;
import com.gitee.jmash.rbac.entity.PermEntity;
import com.gitee.jmash.rbac.model.ResourcePermResult;
import jmash.rbac.protobuf.PermCreateReq;
import jmash.rbac.protobuf.PermModel;
import jmash.rbac.protobuf.PermPage;
import jmash.rbac.protobuf.ResourcePerm;
import jmash.rbac.protobuf.ResourcePermList;

/**
 * PermMapper.
 *
 * @author <a href="mailto:service@crenjoy.com">crenjoy</a>
 */
@Mapper
public interface PermMapper extends BeanMapper, ProtoMapper {

  PermMapper INSTANCE = Mappers.getMapper(PermMapper.class);


  List<PermModel> listPerm(List<PermEntity> list);

  PermPage pagePerm(DtoPage<PermEntity, DtoTotal> page);

  PermModel model(PermEntity entity);

  PermEntity create(PermCreateReq req);

  PermEntity clone(PermEntity entity);

  default ResourcePermList listResourcePerm(List<ResourcePermResult> list) {
    if (list == null || list.size() == 0) {
      return null;
    }
    // 全部资源模型.
    Map<UUID, ResourcePerm.Builder> map = list.stream()
        .collect(Collectors.toMap(ResourcePermResult::getResourceId,
            obj -> PermMapper.INSTANCE.modelPerm(obj).toBuilder(),
            (oldValue, newValue) -> oldValue));
    // 倒序添加孩子
    List<ResourcePermResult> reverseList = new ArrayList<>(list);
    Collections.reverse(reverseList);

    // 数据建立父子关系
    List<UUID> roots = new ArrayList<>();
    for (ResourcePermResult resource : reverseList) {
      ResourcePerm.Builder model = map.get(resource.getResourceId());
      ResourcePerm.Builder parent = map.get(resource.getParentId());
      if (parent == null) {
        roots.add(resource.getResourceId());
      } else {
        parent.addChildren(0, model);
      }
    }
    // 根列表
    ResourcePermList.Builder builder = ResourcePermList.newBuilder();
    for (UUID root : roots) {
      builder.addResults(0, map.get(root));
    }
    return builder.build();
  }

  default ResourcePerm modelPerm(ResourcePermResult result) {
    ResourcePerm.Builder model = ResourcePerm.newBuilder();
    model.setResourceId(toProtoString(result.getResourceId()));
    model.setResourceName(result.getResourceName());
    model.setParentId(toProtoString(result.getParentId()));
    model
        .setPermPrefix(PermEntity.permCodePrefix(result.getModuleCode(), result.getResourceCode()));
    if (result.getPermEntities() != null && result.getPermEntities().size() > 0) {
      for (PermEntity perm : result.getPermEntities()) {
        String permName = perm.getPermName();
        perm.setPermName(permName.substring(permName.lastIndexOf(">") + 1));
        model.addPerms(model(perm));
      }
    }
    return model.build();
  }

}
